package com.neuedu.it.newidea.tools;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.neuedu.it.newidea.po.Cgys;
import com.neuedu.it.newidea.po.Creation;
import com.neuedu.it.newidea.po.User;
import com.neuedu.it.newidea.service.CgysService;
import com.neuedu.it.newidea.service.CreationService;
import com.neuedu.it.newidea.service.UserService;
import com.neuedu.it.newidea.web.dto.CreationSearchRequest;
import com.neuedu.it.newidea.web.dto.UserSearchRequest;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/*
*@Description 注解用于描述 整个工具方法 的功能。
*@JsonPropertyDescription 则用于描述 这个工具方法的某个具体 JSON 参数 的含义和预期用途。
* @JsonPropertyDescription用于我们创建的Java对象
* @ToolParam 用于描述具体Java参数
* */
@Service
@Description("AI function calling Serve for querying database.")
public class AISearchToolService {

    @Autowired
    private CreationService creationService;
    @Autowired
    private UserService userService;
    @Autowired
    private CgysService cgysService;

    //Cgyname to CgyId
    private Integer getCgyIdByName(String categoryName) {
        if (categoryName == null || categoryName.trim().isEmpty()) {
            return null;
        }
        QueryWrapper<Cgys> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Cgys::getCgyname, categoryName.trim());
        Cgys cgys = cgysService.getOne(wrapper);
        return cgys != null ? cgys.getCgyid() : null;
    }

    @Tool(name = "searchCreations")
    @Description("Search for creation records based on title keyword or category_name. Returns a list of matching creations.")
    public List<Creation> searchCreations(@JsonPropertyDescription("Parameters for searching creations, including title keyword and category_name.") CreationSearchRequest request) {
        if (request == null) {
            return Collections.emptyList();
        }

        QueryWrapper<Creation> queryWrapper = new QueryWrapper<>();

        if (request.getTitleKeyword() != null && !request.getTitleKeyword().trim().isEmpty()) {
            queryWrapper.lambda().like(Creation::getTitle, request.getTitleKeyword().trim());
        }

        if (request.getCategoryName() != null && !request.getCategoryName().trim().isEmpty()) {
            Integer cgyId = getCgyIdByName(request.getCategoryName());
            if (cgyId != null) {
                queryWrapper.lambda().eq(Creation::getCgyId, cgyId);
            } else {
                return Collections.emptyList();
            }
        }

        //没有标题关键字和分类名称，返回空列表
        if (request.getTitleKeyword() == null && request.getCategoryName() == null) {
            return Collections.emptyList();
        }

        //page 5
        Page<Creation> page = creationService.page(new Page<>(1, 5), queryWrapper);

        return page.getRecords().stream().map(creation -> {
            if (creation.getCgyId() > 0) {
                Cgys cgys = cgysService.getById(creation.getCgyId());
                if (cgys != null) creation.setCgyName(cgys.getCgyname());
            }
            if (creation.getUserId() > 0) {
                User user = userService.getById(creation.getUserId());
                if (user != null) creation.setUserNickName(user.getNickName());
            }
            return creation;
        }).collect(Collectors.toList());
    }

    @Tool(name = "searchUsers")
    @Description("Search for user records based on nickname, login_name, email, or score range. Returns a list of matching users (without password).")
    public List<User> searchUsers(@JsonPropertyDescription("Parameters for searching users, including nickname, login_name, email, and score range.") UserSearchRequest request) {
        if (request == null) {
            return Collections.emptyList();
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        if (request.getNickname() != null && !request.getNickname().trim().isEmpty()) {
            queryWrapper.lambda().like(User::getNickName, request.getNickname().trim());
        }
        if (request.getLoginName() != null && !request.getLoginName().trim().isEmpty()) {
            queryWrapper.lambda().eq(User::getLoginName, request.getLoginName().trim());
        }
        if (request.getEmail() != null && !request.getEmail().trim().isEmpty()) {
            queryWrapper.lambda().eq(User::getEmail, request.getEmail().trim());
        }
        if (request.getMinScore() != null && request.getMaxScore() != null) {
            queryWrapper.lambda().between(User::getScore, request.getMinScore(), request.getMaxScore());
        } else if (request.getMinScore() != null) {
            queryWrapper.lambda().ge(User::getScore, request.getMinScore());
        } else if (request.getMaxScore() != null) {
            queryWrapper.lambda().le(User::getScore, request.getMaxScore());
        }

        //没有搜索条件，返回空列表
        if(request.getNickname() == null && request.getLoginName() == null &&
                request.getEmail() == null && request.getMinScore() == null && request.getMaxScore() == null){
            return Collections.emptyList();
        }

        List<User> users = userService.list(queryWrapper);
        //过滤敏感信息：密码
        users.forEach(user -> user.setLoginPwd(null));
        return users;
    }

    @Tool(name = "findUserWithHighestScore")
    @Description("Finds the user with the highest score. Returns the user's nickname, login_name, email, and score (without password).")
    public User findUserWithHighestScore() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByDesc(User::getScore).last("LIMIT 1");
        User user = userService.getOne(queryWrapper);
        //过滤敏感信息：密码
        if (user != null) {
            user.setLoginPwd(null);
        }
        return user;
    }
}